#ifndef __VEREMA_GRAPHICSSCENE_H__
#define __VEREMA_GRAPHICSSCENE_H__

#include <QtCore/QObject>
#include <QtGui/QWidget>
#include <QtGui/QGraphicsScene>
#include <QtGui/QGraphicsItem>
#include <QtGui/QGraphicsLineItem>
#include <QtGui/QGraphicsPixmapItem>
#include <QtGui/QGraphicsRectItem>
#include <QtGui/QAbstractGraphicsShapeItem>
#include <QtCore/QPointF>
#include <QtCore/QList>
#include <QtCore/QRectF>
#include <QtGui/QStatusBar>

#include <QtGui/QCursor>

#include <QtGui/QActionGroup>
#include <QtGui/QMenu>

#include "rectangle.h"

namespace verema {

/**
 * \brief class for extended reimplementation of QGraphicsScene to provide a better functionality in cooperation with visual widget
 */
class GraphicsScene : public QGraphicsScene {

    Q_OBJECT

public:
    /**
     * \brief constructor
     */
    GraphicsScene ( QWidget *parent)
    : QGraphicsScene(parent)
    , contextGroup(parent)
    {
        set_background(NULL);
        selected_Item = 0;
        editingMode = SELECT;
        rect = 0;
        left_mousebutton_down = FALSE;
        move_point = QPointF(0,0);

        last_mouseup_pos = QPointF(0,0);
        //status_bar = 0;

        unuse = ContextMenu.addAction( "Frei" );
        unuse->setCheckable(true);
        unuse->setChecked(true);
        use = ContextMenu.addAction( "Besetzt" );
        use->setCheckable(true);
        use->setChecked(false);

        unuse->setActionGroup(&contextGroup);
        use->setActionGroup(&contextGroup);

        connect(use, SIGNAL(toggled(bool)), this, SLOT(useClicked(bool)));
        connect(unuse, SIGNAL(toggled(bool)), this, SLOT(unuseClicked(bool)));


    }

    /**
     * \brief enumeration for the different working modes in the graphicsscene
     */
    enum modes{SELECT, CREATE_RECT_FRAME, CREATE_FREE_FRAME, DELETE, MOVE_FRAME};

    /**
     * \brief set method for selected mode
     * \param selected_mode has to be one of the enumerated types
     */
    void setEditingMode(modes selected_mode);

    /**
     * \brief get method for selected mode
     */
    int getEditingMode(){return(editingMode);};

    /**
     * \brief get method which returns the coordinates of the selected rect
     */
    QRectF get_selected_Item();

    /**
     * \brief returns the background item
     */
    QAbstractGraphicsShapeItem* get_background(){return(gpi_background);};

    /**
     * \brief replaces the old background with the new background item given
     */
    void set_background(QAbstractGraphicsShapeItem *i) {gpi_background = i;};

    /**
     * \brief sets a new background image with the given direct path to the image
     */
    //void setBackgroundImage(QString ImagePath);

    /**
     * \brief selects an item from the scene at the given point
     * \param point the point in the scene where the object shall be selected
     * \return pointer to the selected item
     * \return 0 if nothing is selected (even if the coordinates are on the background image)
     */
    QGraphicsRectItem* select_Rect_Item(QPointF point);

    /**
     * \brief selects a rect item by the given id
     * \param id has to be a valid id or nothing is selected
     */
    void select_Rect_by_Id(int id);

    /**
     * \brief sets the selection to 0
     */
    void reset_Selection();

    /**
     * \brief adds a rect item
     * \param rect_item the coordinates needed to create the rect
     * \param id the id assoziated with the item in database
     */
    void addRectItem(QRectF rect_item, int id, bool used);

    /**
     * \brief removes a rect item
     * \param point the point in the graphicsscene where the item which shall be removed shall be
     */
    void remRectItem(QPointF point);

    /**
     * \brief removes a rect item by id
     * \param id the needed valid id. if the id is invalid nothing is removed
     */
    void rem_Rect_by_Id(int id);

    /**
     * \brief changes the coordinates of the current selected rect
     * \param new_rect the wished new coordinates for the rect
     */
    void changeRect(QRectF new_rect);

    /**
     * \brief returns the current count of rect items in the scene
     */
    int countRect();

    /**
     * \brief removes all rect items from the scene
     */
    void remAllRectItems();

    /**
     * \brief calls function to set the id of the selected Item
     */
    void setSelectedId(int id);

    /**
     * \brief returns the id of the current selected item
     * \return -1 if nothing was found
     */
    int getSelectedId(){return(rect_item_list.id(selected_Item));};

    /**
     * \brief redraws the rect
     */
    void redrawRect(int id);

    /**
     * \brief sets the statusbar
     */
    //void setStatusBar(QStatusBar *statusbar){status_bar = statusbar;};

    /**
     * \brief returns the id of selected_Item
     */
    //int get_selected_Item_id();

protected:

    void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
    void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);

    //void mouseHoverLeaveEvent(QGraphicsSceneMouseEvent

private:
    //temporary creation rect
    QGraphicsRectItem *rect;

    bool left_mousebutton_down;
    int editingMode;
    QAbstractGraphicsShapeItem *gpi_background;
    QGraphicsRectItem *selected_Item;
    Rectangle rect_item_list;
    //QStatusBar *status_bar;

    QMenu ContextMenu;
    QActionGroup contextGroup;
    QAction *use, *unuse;

    QPointF move_point;

    QPointF last_mouseup_pos;
signals:
    /**
     * \brief signal emitted if the pressed mouse button was released
     */
    void mouseReleased();

    /**
     * \brief signal emitted if an item with the given id was removed
     */
    void rectRemoved(int id);

    /**
     * \brief signal emitted if an item with the given coordinates was added
     */
    void rectAdded(QRectF rect_added);

    /**
     * \brief signal emitted when moving in the view
     */
    void moveinView(int x, int y);

    /**
     * \brief signal emittet when a rect was transformed
     */
    void rectChanged(QRectF new_rect/*, int ID*/);

    /**
     * \brief signal emitted when a rect state was changed
     */
    void rectStateChanged(int id, bool state);

private slots:

    /**
     * \brief slot for changing rect status to used
     */
    void useClicked();

    /**
     * \brief slot for changing rect status to unused
     */
    void unuseClicked();

};

}// namespace verema

#endif //__VEREMA_GRAPHICSSCENE_H__
